# 《go 语言实战》 读书笔记
# 第1章 关于 Go 语言的介绍
# 1.1 用 Go 解决现代编程难题
# 1.1.1 开发速度
Go 语言使用了更加智能的编译器,并简化了解决依赖的算法,最终提供了更快的编译速度。 编译 Go 程序时,编译器只会关注那些直接被引用的库,而不是像 Java、C 和 C++那样,要遍历 依赖链中所有依赖的库
# 1.1.2 并发
Go 语言对并发的支持是这门语言最重要的特性之一。goroutine 很像线程,但是它占用的 内存远少于线程,使用它需要的代码更少。通道(channel)是一种内置的数据结构,可以让 用户在不同的 goroutine 之间同步发送具有类型的消息。这让编程模型更倾向于在 goroutine 之间发送消息,而不是让多个 goroutine 争夺同一个数据的使用权。
# 1.1.3 Go 语言的类型系统
在 Go 语言中,一个类型由其他更微小的类型组合而成,避免了传统的基于 继承的模型。
优势:
- 类型简单
- Go 接口对一组行为建模
# 1.1.4 内存管理
想要弄懂 go 语言的代码回收机制,建议扩展阅读一下这篇文章,相信会有更大收获。Golang 垃圾回收剖析 | Legendtkl
# 1.2 你好,Go
package main // Go 程序都组 织成包。
import "fmt" // import 语句用于导入外部代码。标准 库中的 fmt 包用于格式化并输出数据
func main() { // 像 C 语言一样,main 函 数是程序执行的入口。
fmt.Println("Hello world!")
}
文章中介绍了一款在线运行 go 语言的工具 「Go Playground」,网址:http://play.golang.org,感兴趣的可以尝试一下。
# 1.3 小结
- Go 语言是现代的、快速的,带有一个强大的标准库。
- Go 语言内置对并发的支持。
- Go 语言使用接口作为代码复用的基础模块。
# 第2章 快速开始一个Go程序
待补充
# 第3章 打包和工具链
# 3.1 包
什么是包?
- 所有 Go 语言的程序都会组织成若干组文件,每组文件被称为一个包。这样每个包的代码都 可以作为很小的复用单元,被其他项目引用。
包的注意事项:
- 所有的.go 文件,除了空行和注释,都应该在第一行声明自己所属的包
- 每个包都在一个单独的目录里
- 同一个目录下的所有.go 文件必须声明同一个包名
# 3.1.1 包名惯例
给包命名的惯例是使用包所在目录的名字
# 3.1.2 main 包
- 所有用 Go 语言编译的可执行程序都必须有一个名叫 main 的包。
- main()函数是程序的入口,所以,如果没有这个函数,程序就没有办法开始执行。
- 程序编译时,会使用声明 main 包的代码所在的目录的目录名作为二进制可执行文件的文件名。
# 3.2 导入包
import (
"fmt"
"strings" // strings 包提供了很多关于字符串的操作,如查找、替换或 者变换。
)
# 3.2.1 远程导入
使用 go get 命令完成包的远程导入
# 3.2.2 命名导入
如果遇到导入的包名重名情况,可以使用命名导入的形式,命名导入是指,在 import 语句给出的包路径的左侧定义一个名字,将导入的包命名为新名字。
import (
"fmt"
myfmt "mylib/fmt"
)
注意:当你导入了一个不在代码里使用的包时,Go 编译器会编译失败,并输出一个错误。
如果你需要导入一个包,但是不需要引用这个包的标识符(有一种情况是,导入一个包,目的是执行包内的init
函数),则可以使用空白标识符_
来重命名这个导入
import (
_ "mylib/fmt"
)
概念补充:
空白标识符 下划线字符(_)在 Go 语言里称为空白标识符,有很多用法。这个标识符用来抛弃不 想继续使用的值,如给导入的包赋予一个空名字,或者忽略函数返回的你不感兴趣的值。
# 3.3 函数 init
- 每个包可以包含任意多个
init
函数 init
函数都会在程序执行开始的时候被调用(main 函数之前调用)
作用:init
函数用在设置包、初始化变量 或者其他要在程序运行前优先完成的引导工作。
文中案例:
package postgres
import (
"database/sql"
)
func init() {
sql.Register("postgres", new(PostgresDriver))
}
package main
import (
"database/sql"
_ "github.com/goinaction/code/chapter3/dbdriver/postgres"
)
func main() {
sql.Open("postgres", "mydb")
}
# 3.4 使用 Go 的工具
go build // 构建包
go run main.go //构建并执行
# 3.5 进一步介绍 Go 开发工具
go vet // 检测代码的常见错误
go fmt // Go 代码格式化
go doc XXX(包名) // 从命令行获取文档
godoc -http=:6060 // 开启一个文档服务器
# 3.6 与其他 Go 开发者合作
- 包应该在代码库的根目录中
- 包可以非常小
- 对代码执行go fmt
- 给代码写文档
# 3.7 依赖管理
不建议去学习书中提到的 godep、vender 和 gb等工具,建议去了解一下 go module
# 3.8 小结
- 在 Go 语言中包是组织代码的基本单位。
- 环境变量 GOPATH 决定了 Go 源代码在磁盘上被保存、编译和安装的位置。
- 可以为每个工程设置不同的 GOPATH,以保持源代码和依赖的隔离。
- go 工具是在命令行上工作的最好工具。
- 开发人员可以使用go get来获取别人的包并将其安装到自己的GOPATH指定的目录。
- 想要为别人创建包很简单,只要把源代码放到公用代码库,并遵守一些简单规则就可以了。
- Go 语言在设计时将分享代码作为语言的核心特性和驱动力。
- 推荐使用依赖管理工具来管理依赖。
- 有很多社区开发的依赖管理工具,如 godep、vender 和 gb。
# 第4章 数组、4切片和映射(重要)
# 第 7 章 并发模式
# 7.1 runner
runner 介绍:runner 包用于展示如何使用通道来监视程序的执行时间,如果程序运行时间太长,也可以 用 runner 包来终止程序
设计特点:
- 程序可以在分配的时间内完成工作,正常终止;
- 程序没有及时完成工作,“自杀”;
- 接收到操作系统发送的中断事件,程序立刻试图清理状态并停止工作。